
import logging
import json
import time
from datetime import datetime
import types

from datastore import *
from runtime.task import Task
from runtime.spaces import *
from runtime.node import LoggingLevels
from services import *
from services.httpserver import *       # FIXME: not sure why I need this

class TransformTask(Task):
    """
    The purpose of this class is ... 
    """
    
    # Class constants
    #
        
    def cb_start(self, method, uri, new_uri, result, context, **kwargs):
        """This function is called when the task starts. Register all templates 
        as html:template/xxx for the template Resource and html:template/xxx/ 
        for the generation function.
        
        :param method: <class> or <type>
        :param uri: The task Uri.
        :param new_uri: <class> or <type>
        :param result: <class> or <type>
        :param context: <class> or <type>
        :param kwargs: <class> or <type>
        """
        
        self.template = self.spaces_context.uri('transform:').template
        self.template_list = {'dump': self.template.dump}
        #
        for template in self.template_list:
            # TODO: fetch the template Resource from the datastore.
            # TODO: put it to html:template/xx to allow access during generation.
            watch_put_key = self.spaces_context.process(self.template_list[template].collection(), put='cb_generate')
            self.logger.log(logging.DEBUG, "Add process(put) for: %s" % self.template_list[template])
        
        #assume that we put the real resource after generation.
        #watch_remove_key = self.spaces_context.process_all(self.templates, remove='cb_fetch')
        #
    
    def cb_generate(self, method, uri, res, result, context, **kwargs):
        '''
        Generate transformed resource as a result of a 'put' to  'put'.
        The resource containing the input data is passed to this callback.
        Doesn't return until generation is complete.
        Returns the URI of the transformed resource.
        '''
        # we only want to process puts by the user of this API, not ours...
        if uri in self.template_list.values():
            gen_uri = uri.add(self.spaces_context.uuid())
            self.logger.log(logging.DEBUG, "Creating transformed resource (%s) using: %s" % (gen_uri, str(res)))
            html_res = Resource()
            html = ''
            if uri == context.uri('transform:template/dump/'):
                # The built-in template creates a hard-coded HTML dump of any Resource.
                html += '<html>\n<body>\n'
                html += '<h1>Metadata</h1>\n<table border=1>\n'
                for meta in res.get_metadata_keys():
                    html += '<tr><td valign="top">%s</td valign="top"><td>' % meta
                    for value in res.get_metadata(meta):
                        html += '%s<br>' % value
                    html += '</td></tr>\n'
                html += '</table>\n'
                html += '<h1>Data</h1>\n'
                html += self._gen_html(res.get_vars())
                #html += '<hr><small>generated HTML URI: %s - %s</small>\n' % (gen_uri.full(), datetime.now())
                html += '<hr><small>generated URI: %s - %%s</small>\n' % gen_uri.full()
                html += '</body></html>\n'
                #
                def fix_footer(html):
                    from datetime import datetime
                    return html % datetime.now()
                html_res.finalise = [fix_footer]
            else:
                html = "<html>%s</html>" % res.hello
            html_res.content = html
            context.put(gen_uri, html_res)
            return (True, gen_uri)
        else:
            self.logger.log(logging.ERROR, "Template not found for: %s" % uri)
            return (True, None)

    def _gen_html(self, var):
        html = ''
        if type(var) in [types.DictType, type(ResourceDict())]:
            html += '<table border=1>\n'
            keys = var.keys()
            keys.sort()
            for key in keys:
                html += '<tr>'
                html += '<td valign="top">%s</td>' % key
                html += '<td valign="top">%s</td>' % self._gen_html(var[key])
                html += '</tr>\n'
            html += '</table>\n'
        elif type(var) in [types.ListType, types.TupleType]:
            html += '<table border=1>\n'
            for value in var:
                html += '<tr>'
                html += '<td valign="top">%s</td>' % self._gen_html(value)
                html += '</tr>\n'
            html += '</table>\n'
        else:
            html += var
        return html
    
#    def cb_fetch (self, method, uri, return_value, result, context):
#        '''
#        Retrieve the resource with the generated HTML and then delete it using 'remove'.
#        Returns a resource containing the generated HTML.
#        '''
#        res = self.spaces_context.get(uri)
#        return (True, res)


#if __name__ == "__main__":
#    pass
    
